#pragma once
// 网络地址和主机地址之间进行转换的类
#include <iostream>
#include <netinet/in.h>
#include<string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Common.hpp"

class InetAddr{
    public:
    //构造函数
    InetAddr(){}
    InetAddr(sockaddr_in& a)//便于accept使用
    {
        SetAddr(a);
    }
    InetAddr(const std::string Ip,uint16_t Port)//从ip和端口号直接构造
    :_ip(Ip),_port(Port)
    {
        memset(&_addr,0,sizeof(_addr));
        _addr.sin_family = AF_INET;
        inet_pton(AF_INET,_ip.c_str(),&_addr.sin_addr);
        _addr.sin_port = htons(_port);
    }
    InetAddr(uint16_t Port)//仅从端口构造：用于服务器端绑定到所有网卡（INADDR_ANY）的场景
    :_port(Port),_ip()
    {
        memset(&_addr,0,sizeof(_addr));
        _addr.sin_family = AF_INET;
        _addr.sin_addr.s_addr = 0;//也可以是INADDR_ANY，socket INADDR_ANY表示的是一个服务器上所有的网卡
        _addr.sin_port = htons(_port);
    }
    //设置地址
    void SetAddr(struct sockaddr_in& a){
        _addr = a;
        _port = ntohs(_addr.sin_port);
        // 从网络中拿到的！网络序列
        //_ip = inet_ntoa(_addr.sin_addr);
        char buf[64];
        inet_ntop(AF_INET,&_addr.sin_addr,buf,sizeof(buf));
        _ip = buf;
    }
    
    //方法
    uint16_t GetPort(){
        return _port;
    }
    std::string GetIp(){
        return _ip;    
    }
    const sockaddr_in &NetAddr(){
        return _addr;
    }
    sockaddr* NetAddrPtr(){
        return CONV(_addr);
    }
    std::string StringAddr()//返回一个格式化的字符串告诉日志哪个客户端退出了
    {
        return _ip + std::to_string(_port);
    }
    socklen_t NetAddrlen(){
        return sizeof(_addr);
    }

    //重载
    bool operator==(const InetAddr& a){
        return a._ip == _ip&&a._port == _port;
    }
    ~InetAddr(){}
    private:
    struct sockaddr_in _addr;//储存ipv4的地址信息
    //包括协议族（sin_family）、端口号（sin_port）和 IP 地址（sin_addr）
    std::string _ip;
    uint16_t _port;

};


